<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style type="text/css">
			* {
				margin: 0;
				padding: 0;
			}

			html,
			body {
				width: 100%;
				height: 100%;
			}

			body {
				background-color: #000;
			}

			#myCanvas {
				position: absolute;
				z-index: 1;
			}

			input[type="range"] {
				width: 400px;
			}

			.ui {
				display: none;
				color: #fff;
			}

			.inline {
				display: flex;
				height: 60px;
				align-items: center;
			}

			.txt {
				margin-right: 20px;
			}

			.btn-area {
				position: fixed;
				left: 0;
				top: 0;
				width: 160px;
				height: 100%;
				padding-top: 20px;
				background-color: #00000022;
				z-index: 2;
				transition: .2s;
			}

			.btn-area:hover {
				background-color: #99999944;
			}

			.cell {
				width: 100%;
				height: 50px;
				box-sizing: border-box;
				padding: 0 20px;
				line-height: 50px;
				color: #c5c5c5aa;
				text-align: center;
				user-select: none;
				cursor: pointer;
				transition: .3s;
			}

			.cell:hover {
				color: #fff;
				background-color: #00000033;
			}

			.cell.act {
				color: #fff;
				background-color: #00000088;
			}

			.btn {
				border-bottom: 1px solid #ffffff55;
			}
		</style>
	</head>
	<body>
		<div id="funButtons" class="btn-area">
			<div class="cell"> <div data-index="0" class="btn">mode 1</div> </div>
			<div class="cell"> <div data-index="1" class="btn">mode 2</div> </div>
			<div class="cell"> <div data-index="2" class="btn">mode 3</div> </div>
			<div class="cell"> <div data-index="3" class="btn">mode 4</div> </div>
			<div class="cell"> <div data-index="4" class="btn">mode 5</div> </div>
			<div class="cell"> <div data-index="5" class="btn">mode 6</div> </div>
			<div class="cell act"> <div data-index="6" class="btn">test mode 7</div> </div>
		</div>
		<canvas id="myCanvas" width="800" height="800"></canvas>
		<script type="text/javascript" src="tCanvas.js"></script>
		<script type="text/javascript">
			Particle.prototype.mode7 = function() {
				this.dis = 5000
				this.zoomQuotiety = 5
				// 新建一个立方体面队列
				this.fList = []
				var pA = [400,-400,400]
				var pB = [-400,-400,400]
				var pC = [-400,400,400]
				var pD = [400,400,400]
				var pE = [400,-400,-400]
				var pF = [-400,-400,-400]
				var pG = [-400,400,-400]
				var pH = [400,400,-400]
				this.fList.push({ // front
					anchor: [pA,pB,pC,pD],
					color: "hsl(206, 81%, 54%)",
					h: 206,
					s: 81,
					l: 54
				})
				this.fList.push({ // back
					anchor: [pE,pH,pG,pF],
					color: "hsl(129, 33%, 83%)",
					h: 129,
					s: 33,
					l: 83
				})
				this.fList.push({ // down
					anchor: [pC,pG,pH,pD],
					color: "hsl(358, 18%, 90%)",
					h: 358,
					s: 18,
					l: 90
				})
				this.fList.push({ // up
					anchor: [pA,pE,pF,pB],
					color: "hsl(255, 43%, 68%)",
					h: 255,
					s: 43,
					l: 68
				})
				this.fList.push({ // left
					anchor: [pB,pF,pG,pC],
					color: "hsl(359, 56%, 71%)",
					h: 359,
					s: 56,
					l: 71
				})
				this.fList.push({ // right
					anchor: [pE,pA,pD,pH],
					color: "hsl(20, 66%, 66%)",
					h: 20,
					s: 66,
					l: 66
				})
				// 新建一个平行光源
				this.lightList.push({
					type: "parallel",
					vector: [-1,1,-1],
					// vector: [0,0,-1],
					lightness: 90
				})
				this.lightList.push({
					type: "parallel",
					vector: [0,1,0],
					lightness: 30
				})
				// 新建一个环境光
				this.lightList.push({
					type: "env",
					vector: [1,0,0],
					lightness: 10
				})
				// 绘制
				this.draw(() => {
					// 根据面重心的 z 坐标升序排序面，为的是让 z 越小越先被绘制
					this.fList.sort((fa,fb)=>{
						var z = f => {
							return f.anchor.reduce((pre,next)=>{
								var p2d = this.deDiv(next)
								return pre + p2d.origin[2]
							},0) / f.anchor.length
						}
						return z(fa) - z(fb)
					})
					this.fList.forEach(f => {
						var lightness = 0 // 初始化着色强度
						var fSource = [] // 计算单个面的 3 个点立体坐标
						f.anchor.forEach((an, i) => {
							if(i < 3){
								fSource.push(this.deDiv(an).origin)
							}else{
								return
							}
						})
						var vx = this.getNVector(...fSource) // 计算面法向量
						this.lightList.forEach(light=>{ // 计算总着色强度
							if(light.type == "env"){
								lightness += light.lightness
							}else if(light.type == "parallel"){
								lightness += this.getVectorCos(vx,light.vector) * light.lightness
							}
						})
						// this.cx.fillStyle = "hsl("+f.h+","+f.s+"%,"+f.l*lightness/100+"%)" // 设置颜色
						this.cx.fillStyle = "hsl(0,0%,"+lightness+"%)"
						this.cx.beginPath()
						var able = true
						f.anchor.forEach((an, i) => {
							var p2d = this.deDiv(an)
							if (p2d.mul < 0) {
								able = false
								return
							}
							this.cx[i == 0 ? 'moveTo' : 'lineTo'](...p2d.res)
						})
						able && this.cx.fill()
					})
				})
			}
			var pDemo = new Particle({
				mode: 7,
			})

			// 以下是栏目切换
			function switchMode(modeIndex) {
				pDemo.destroy()
				pDemo = new Particle({
					mode: modeIndex,
					preEmit: true,
				})
			}
			funButtons.onclick = e => {
				var index = Number(e.target.dataset.index)
				var c = Array.from(e.currentTarget.children)
				c.forEach((el, i) => {
					el.classList[i == index ? 'add' : 'remove']("act")
				})
				switchMode(index + 1)
			}
		</script>
	</body>
</html>
